package com.sense.cloud.coreservice.sdk.auth.filter;

import com.alibaba.fastjson.JSON;
import com.sense.cloud.coreservice.sdk.auth.annotation.CodeWithHandler;
import com.sense.cloud.coreservice.sdk.auth.modules.ChkResult;
import com.sense.cloud.coreservice.sdk.auth.modules.ErrorCode;
import com.sense.cloud.coreservice.sdk.auth.modules.UserAppService;
import com.sense.cloud.coreservice.sdk.auth.utils.StringUtils;
import com.sense.cloud.coreservice.sdk.auth.utils.http.assist.AuthConstants;
import com.sense.cloud.coreservice.sdk.auth.wrapper.BodyHttpServletRequestWrapper;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CodeAuthWebFilter implements Filter {
  private Logger         log = LoggerFactory.getLogger(getClass());
  private UserAppService userAppService;
  
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    userAppService = new UserAppService();
    String packages = filterConfig.getInitParameter("apiPath");
    CodeWithHandler.getInstance().scanner(packages);
  }
  
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    HttpServletRequest httprequest = (HttpServletRequest) request;
    HttpServletResponse httpresponse = (HttpServletResponse) response;
    
    //
    if ("GET".equalsIgnoreCase(httprequest.getMethod())) {
      //
      String url = httprequest.getRequestURL().toString() + "?" + httprequest.getQueryString();
      
      checkCode(url, httpresponse);
      
      ChkResult res = userAppService.validateGet(url);
      
      if (res.isResult()) {
        chain.doFilter(httprequest, httpresponse);
      } else {
        httpresponse.setContentType("application/json");
        httpresponse.setCharacterEncoding("UTF-8");
        String resStr = JSON.toJSONString(res);
        httpresponse.setStatus(401);
        httpresponse.getWriter().write(resStr);
        httpresponse.getWriter().flush();
        httpresponse.getWriter().close();
        log.error("get " + resStr);
      }
    } else {
      BodyHttpServletRequestWrapper requestWrapper = new BodyHttpServletRequestWrapper(httprequest);
      
      String url = requestWrapper.getRequestURL().toString() + "?" 
          + requestWrapper.getQueryString();
      
      checkCode(url, httpresponse);//
      
      byte[] b2 = requestWrapper.getBody();
      ChkResult res = userAppService.validatePost(url, b2);
      if (res.isResult()) {
        chain.doFilter(requestWrapper, httpresponse);
      } else {
        httpresponse.setContentType("application/json");
        httpresponse.setCharacterEncoding("UTF-8");
        String resStr = JSON.toJSONString(res);
        httpresponse.setStatus(401);
        httpresponse.getWriter().write(JSON.toJSONString(resStr));
        httpresponse.getWriter().flush();
        httpresponse.getWriter().close();
        log.error("post " + resStr);
      }
    }
    //
    
  }
  
  @Override
  public void destroy() {
    userAppService = null;
  }
  
  private void checkCode(String url, HttpServletResponse httpresponse) {
    try {
      // code check
      int ssaccesskeyIndex = url.indexOf(AuthConstants.ACCESSKEY);
      int ssnonceIndex = url.indexOf(AuthConstants.NONCE);
      String ssaccesskey =
          url.substring(ssaccesskeyIndex + AuthConstants.ACCESSKEY.length() + 1, ssnonceIndex - 1);
      String action = StringUtils.getAction(url);
      boolean chkRes = CodeWithHandler.getInstance().checkUriCode(action, ssaccesskey);
      
      if (!chkRes) {
        httpresponse.setContentType("application/json");
        httpresponse.setCharacterEncoding("UTF-8");
        ChkResult res = new ChkResult();
        res.setResult(false);
        res.setStatus(ErrorCode.ERROR_PERMISSIONS);
        String resStr = JSON.toJSONString(res);
        httpresponse.setStatus(401);
        httpresponse.getWriter().write(resStr);
        httpresponse.getWriter().flush();
        httpresponse.getWriter().close();
        log.error("get " + resStr);
      }
    } catch (Exception ee) {
      ee.printStackTrace();
    }
  }
  
}
